/* main.cc
   Written by, Sohail Qayum Malik[sqm@cyberian.pk] */

#include "main.hh"

int help(argument<arg_history>::iterator itB, argument<arg_history>::iterator itE, std::string commands) {

   int ret = 0;
   
   std::cout<<"---- In the help() ---- "<<std::endl;
   
   while ( itB != itE ) {
   
      arg_history::value_type foo = *(itB++);
      
      if ( foo.get_arg() ) {
      
         std::cout<<foo.get_arg()<<", "<<commands.substr(foo.get_pos(), foo.get_cmd_size())<<", "<<commands.substr(foo.get_pos() + foo.get_cmt_head_pos(), foo.get_cmt_size())<<std::endl;
      }
      else {
         std::cout<<"NULL(You did not issued this command), "<<commands.substr(foo.get_pos(), foo.get_cmd_size())<<", "<<commands.substr(foo.get_cmt_head_pos(), foo.get_cmt_size())<<std::endl;
      }
   }
}

int main(int argc, char* argv[]) {

   int ret = 0;
   argument<arg_history>::pointer ptr;

   //Two stage construction. Prefer this over other ways of construction
   //Container is not default constructible...
   //              argument obj; // Not possible
   //Many iterators can be active at the same time in the same container
   //The resources to iterate upon are reference counted and are not collected
   //untill the last iterator finishes and goes out of scope
   //The container is the model of Random Access Conatiner
   //The Iterator is the model of Random Access Iterator
   try {

      ptr = argument<arg_history>::NewE(argc, argv, COMMANDS);
      
      argument<arg_history>::iterator itB(ptr->begin()); /* An iterator at the beginning */
      argument<arg_history>::iterator itE(ptr->end()); /* An iterator at the end */
      
      arg_history bar = itB[COMMON];
      
      if ( itB == itE ) {
      
         std::cout<<"No commands are given at CLI"<<std::endl;
         
         /* Check for the common CLI arguments, these are token which you put on the command line right after the name of the application(which you are about to execute) */
         std::cout<<"COMMON argc = "<<bar.get_argc()<<std::endl;
      }
      else {
      
         std::cout<<"COMMON argc = "<<bar.get_argc()<<std::endl;
        
         /* Iterate over all commands given at command line */ 
         while ( itB != itE ) {
         
            arg_history foo;
        
            /* See if this is the one specific command we are looking for */     
               if ( *itB == HELP ) {
            
                  std::cout<<"Hold on, I'm coming. *itB == HELP "<<std::endl;
               } 
            
               /* Not pretty */
               if ( (*itB)(HELP) ) { 
               
                  std::cout<<"Hold on, I'm coming. (*itB)(HELP) "<<std::endl;
               }
           
               /* Bit more description but, very pretty(prettyness is in the eyes of the person holding those eyes) */ 
               foo = *itB;
               if ( foo(HELP) ) {
            
                  std::cout<<"Hold on, I'm coming. foo(HELP)"<<std::endl;
               }
           
            /* Any command, in short or long form */ 
            arg_history baz = *itB;
           
            /* Is this command given by the user at command prompt */  
            if ( baz.get_arg() ) {
            
               std::cout<<"argv[index] = "<<baz.get_arg()<<", where index = "<<baz.get_index();
            
               if ( foo.is_short() ) {
              
                  std::cout<<", it is a short command and it appers "<<baz.get_appears()<<" time/s"; 
               }
               else {
            
                  std::cout<<", its a long command";
               }
               
               std::cout<<". Number of arguments to this command is "<<baz.get_argc()<<std::endl;
            }   
                           
            itB++;
         }
      }
      
      /* The iterator is also random accessable */
      /* so itB[HELP] == HELP is possible as is itB[HELP]() but lets not use them... instead use... */
      if ( /* itB[HELP]() && itB[HELP] == HELP && */ itB(HELP) ) {
      
         argument<arg_history>::iterator itB(ptr->begin());
         argument<arg_history>::iterator itE(ptr->end());
         
         help(itB, itE, COMMANDS);
      }
      
      
      delete ptr;
   }
   catch (args_exception &excp) {

      std::cout<<excp.what();

      ret = 1;
   }

   return ret;
}

